package ui.home

import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import cn.hutool.core.util.IdUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import model.db.Db
import model.dto.ProcessApplyDto
import model.enums.ChannelMappingTabSelect
import model.enums.ContentType
import model.enums.MenuItem
import model.network.netty.NettyClient
import model.repository.ChannelMappingRepository
import model.repository.UserRepository
import model.vo.*
import state.ApplicationWindowsState
import state.WindowType
import ui.phone.PoneUser
import utils.TimeStringUtil
import java.time.LocalDateTime

class HomeViewModel(
    val applicationWindowsState: ApplicationWindowsState,
    private val coroutineScope: CoroutineScope
) {
    //聊天标题
    val chatTitle = mutableStateOf("聊天标题")

    //最左侧菜单选了什么
    val leftMenuSelected = mutableStateOf(MenuItem.Chat)

    //消息列表选择的itemId
    val msgListItemSelectId = mutableStateOf(0L)

    //最右边显示的内容类型
    val column3ContentType = mutableStateOf(ContentType.NONE)

    //不同类型时的渲染数据
    val column3FriendChatInformation = mutableStateOf(null)
    val column3GroupChatInformation = mutableStateOf(null)
    val column3FriendInformation = mutableStateOf(null)

    //头像url
    val headUrl = mutableStateOf("")

    //搜索框输入文本
    val searchText = mutableStateOf("")

    //消息列表
    val messageList = mutableStateListOf<MessageListItem>()

    //聊天框消息列表
    val messageContentItemList = mutableStateListOf<MessageContentItem>()

    //好友列表
    val friendsMappingItems = mutableStateListOf<FriendsMappingItem>()

    //群列表
    val groupMappingItems = mutableStateListOf<GroupMappingItem>()

    //群通知列表
    val groupNotificationItems = mutableStateListOf<GroupNotificationItem>()

    //好友通知列表
    val friendNotificationItems = mutableStateListOf<FriendNotificationItem>()

    //选择消息映射列表时，是好友列表还是群列表
    val channelMappingTabSelected = mutableStateOf(ChannelMappingTabSelect.Friends)

    //输入发送内容
    val textInput = mutableStateOf("")

    //是否弹出创建群聊对话框
    val createGroupDialog = mutableStateOf(false)

    init {
        NettyClient.setHomeViewModel(this@HomeViewModel)
        headUrl.value = UserRepository.user?.avatar ?: ""
        NettyClient.startClient()//开始心跳
        //将通知渲染
        val friendNotices = Db.getFriendNotices()
        if (friendNotices != null) {
            friendNotificationItems.addAll(friendNotices)

        }
        val groupNotices = Db.getGroupNotices()
        if (groupNotices != null) {
            groupNotificationItems.addAll(groupNotices)

        }
        val friends = Db.getFriends()
        if (friends != null) {
            friendsMappingItems.addAll(friends)
            friendsMappingItems.forEach {
                ChannelMappingRepository.channelMappingAccountList.add(it.account)
            }
        }
        //消息记录
        val messageListMap = mutableMapOf<String, MutableList<MessageContentItem>>()
        val msgSqlDTOs = Db.getMessages()
        if (!msgSqlDTOs.isNullOrEmpty()) {
            msgSqlDTOs.forEach {
                if (messageListMap.containsKey(it.userAccount + "-" + it.toUserAccount + "-" + it.isGroup)) {
                    messageListMap[it.userAccount + "-" + it.toUserAccount + "-" + it.isGroup]!!.add(
                        MessageContentItem(
                            id = it.id!!.toLong(),
                            userAccount = it.userAccount.toString(),
                            userName = it.userName.toString(),
                            userHeadImageUrl = it.userAvatar.toString(),
                            content = it.getMsgContent(),
                            time = it.time.toString()
                        )
                    )
                } else
                    messageListMap[it.userAccount + "-" + it.toUserAccount + "-" + it.isGroup] = mutableListOf(
                        MessageContentItem(
                            id = it.id!!.toLong(),
                            userAccount = it.userAccount.toString(),
                            userName = it.userName.toString(),
                            userHeadImageUrl = it.userAvatar.toString(),
                            content = it.getMsgContent(),
                            time = it.time.toString()
                        )
                    )
            }
        }

        val messageListItems = Db.getMsgLists()
        if (messageListItems != null) {
            //给每个消息列表设置消息记录内容
            messageListItems.forEach {
                if (messageListMap.containsKey(it.account + "-" + UserRepository.user?.account + "-" + it.isGroup)) {//别人发给自己的
                    it.messageContentItems += messageListMap[it.account + "-" + UserRepository.user?.account + "-" + it.isGroup]!!
                }
                if (messageListMap.containsKey(UserRepository.user?.account + "-" + it.account + "-" + it.isGroup)) {//自己发给别人的
                    it.messageContentItems += messageListMap[UserRepository.user?.account + "-" + it.account + "-" + it.isGroup]!!
                }
                it.id = IdUtil.getSnowflakeNextId()
            }
            //排序消息记录内容
            messageListItems.forEach {
                val sorted = it.messageContentItems.sortedWith(compareByDescending { it1 ->
                    LocalDateTime.parse(it1.time)
                })
                it.messageContentItems = sorted
            }
            messageList.addAll(messageListItems)
        }

        val groups = Db.getGroups()
        if (!groups.isNullOrEmpty()) {
            groupMappingItems.addAll(groups)
        }
        //以下是假数据

    }

    fun onAddClick() {
        applicationWindowsState.newWindow(WindowType.Search)
    }

    fun processFriendRequest(applyState: String, applyId: Long, friendAccount: String) {
        coroutineScope.launch(Dispatchers.IO) {
            val processApplyDto = ProcessApplyDto(applyId = applyId, state = applyState)
            ChannelMappingRepository.processFriendRequest(processApplyDto, friendAccount, this@HomeViewModel)
        }
    }

    /**
     * 打开语音通话
     */
    fun openPhone() {
        if (applicationWindowsState.isExist(WindowType.Phone)) return
        //通话对象信息
        val messageListItem = messageList.find { msgListItemSelectId.value == it.id } ?: return
        PoneUser.messageListItem = messageListItem
        //打开通话窗口，在通知窗口初始化方法中开始通话
        applicationWindowsState.newWindow(WindowType.Phone)
    }

    fun sendTextMsg(content: String) {
        val messageListItem = messageList.find { msgListItemSelectId.value == it.id } ?: return
        val account = messageListItem.account
        val group = messageListItem.isGroup
        //更新聊天框
        val index = messageList.indexOf(messageListItem)
        //删除原来的
        messageList.remove(messageListItem)
        //修改
        messageListItem.msg = content
        messageListItem.time = LocalDateTime.now().toString()
        messageListItem.messageContentItems = listOf(
            MessageContentItem(
                id = IdUtil.getSnowflakeNextId(),
                userAccount = UserRepository.user?.account!!,
                userName = UserRepository.user?.username!!,
                userHeadImageUrl = UserRepository.user?.avatar!!,
                content = content,
                time = messageListItem.time
            )
        ) + messageListItem.messageContentItems
        //更新UI
        messageList.add(index, messageListItem)
        messageContentItemList.add(0, messageListItem.messageContentItems[0])
        //更新数据库
        Db.saveMsgList(messageListItem)
        //发送
        account.let {
            group.let { it1 ->
                NettyClient.sendTextMsg(
                    messageListItem.messageContentItems[0],
                    it,
                    it1
                )
            }
        }
    }
}